// Copyright (C) Microsoft Corporation. All rights reserved.

using System;
using System.Collections.Generic;
using System.Collections;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Resources;
using System.Reflection;
using System.Globalization;
using System.Xml;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Proxy;


namespace  Microsoft.DDSolutions.TfsAdmin
{
    public enum UserEditStatus { Initial = 'I', Add = 'A', Delete = 'D', Change = 'C', Error = 'E', None = 0 };

    public partial class MainForm : Form
    {
        private Splash connecting ;
        private DataSet actionLog ;
        bool newRowNeeded ;
        int numberOfRows ;
        int startTransaction;
        DataSet ds;
        private int bitmapPadding = 6;
        private bool ignoreEdit;

        private TeamFoundationServer tfsAppServer;

        private Icon userIcon = new Icon(MainResources.userIcon, new Size(16, 16));
        private Icon newuserIcon = new Icon(MainResources.new_user, new Size(16, 16));
        private Icon adduserIcon = new Icon(MainResources.newadduser, new Size(16, 16));
        private Icon removeuserIcon = new Icon(MainResources.delete_user, new Size(16, 16));
        private Icon modifyuserIcon = new Icon(MainResources.propertiesORoptions, new Size(16, 16));
        private Icon erroruserIcon = new Icon(MainResources.warning, new Size(16, 16));
        private Font defaultFont;
        private Font selectedFont;

        private TreeNode selectedNode;


        //string prevTfsUser = "";
        /// <summary>
        ///    Initialize the data sets needed for the GUI display and also create a Splash screen instance.
        ///  This splash screen would be displayed during long server calls.
        /// </summary>
        public MainForm()
        {
            InitializeComponent();

            // Create the fonts used by the TreeView
            defaultFont = new Font(treeView.Font, FontStyle.Regular);
            selectedFont = new Font(treeView.Font, FontStyle.Bold);

            this.lblHelp.Text = MainResources.strHelp;
            this.lblLogin.Text = MainResources.LableLoginText;
            this.toolStripBtnRefresh.Text = MainResources.strRefresh;
            this.toolStripBtnUsersGroupsPicker.Text = MainResources.SelectUsersOrGroupsBtnTxt;
            this.Text = MainResources.AppTitleText;

            //. User
            connecting = new Splash();

            //connecting.MdiParent = this;
            //this.LayoutMdi(MdiLayout.TileVertical);


            actionLog = new DataSet("Transactions");

            //. Create a table 
            actionLog.Locale = CultureInfo.CurrentUICulture;
            actionLog.Tables.Add("ActionLog");
            actionLog.Tables.Add("AllTransactions");

            actionLog.Tables[0].Columns.Add("Action");
            actionLog.Tables[0].Columns.Add("User");
            actionLog.Tables[0].Columns.Add("DisplayName");
            actionLog.Tables[0].Columns.Add("Tier");
            actionLog.Tables[0].Columns.Add("Role");
            actionLog.Tables[0].Columns.Add("Status");
            actionLog.Tables[0].Columns.Add("Comments");


            actionLog.Tables["AllTransactions"].Columns.Add("Action");
            actionLog.Tables["AllTransactions"].Columns.Add("User");
            actionLog.Tables["AllTransactions"].Columns.Add("DisplayName");
            actionLog.Tables["AllTransactions"].Columns.Add("Tier");
            actionLog.Tables["AllTransactions"].Columns.Add("Role");
            actionLog.Tables["AllTransactions"].Columns.Add("State");

        }


        private void button1_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            /// Create a new controller object when you change team projects.
            AppController = new Controller();
            toolStripBtnSave.Enabled = false;
            toolStripBtnSave.Visible = false;
            toolStripBtnUsersGroupsPicker.Enabled = false;
            toolStripBtnUsersGroupsPicker.Visible = false;
            lblHelpMessage.Text = MainResources.HelpMessage2;
            this.aboutButton.Text = MainResources.AboutBtnText;
            this.toolStripBtnSave.Text = MainResources.CommitBtnText;
            this.toolStripBtnRefresh.Text = MainResources.RefreshBtnText;
            this.toolStripBtnUsersGroupsPicker.Text = MainResources.SelectUsersOrGroupsBtnTxt;
            this.toolStripBtnUsersGroupsPicker.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText;
            this.btnLogin.Text = MainResources.LoginBtnText;
            EventArgs args = new EventArgs();
            btnLogin_Click(this, args);




            //. DataGridView
            SetupDataGridViewColumns();

            dataGridView1.Visible = false;
            dataGridView1.Enabled = false;
        }

        /// <summary>
        ///   On user clicking the Login button the following is invoked.
        /// </summary>
        /// <param name="sender">Sending Control</param>
        /// <param name="e">Arguments</param>
        private void btnLogin_Click(object sender, EventArgs e)
        {
            MessageBoxOptions mbOptions = new MessageBoxOptions();

            if (this.RightToLeft == RightToLeft.Yes)
                mbOptions = mbOptions | MessageBoxOptions.RtlReading;

            try
            {

                lblHelpMessage.Text = MainResources.HelpMessage1;

                ///Gets a fully authenticated TeamFoundationServer instance
                tfsAppServer = ChooseAppServer();
                
                connecting.Show();
                connecting.Activate();
                Application.DoEvents();

                ReadOnlyCollection<string> projects = AppController.OnTFSLogin(tfsAppServer);
                this.lblLogin.Text = MainResources.LoggedOn + tfsAppServer.Name;

                PopulateTreeView(projects);

                this.LoginPanel.Visible = false;

                /// In case the user swiches between logged in users we need to clear the list.
                /// Clearing removes the column also. So need to reset the key properties.

                this.toolStripBtnSave.Enabled = false;
                this.toolStripBtnSave.Visible = false;
                this.toolStripBtnUsersGroupsPicker.Enabled = false;
                this.toolStripBtnUsersGroupsPicker.Visible = false;

                this.TeamProjectsPanel.Visible = true;
                this.TeamProjectsPanel.Location = this.LoginPanel.Location;
                this.dataGridView1.Enabled = false;
                this.dataGridView1.Visible = false;
                connecting.Hide();
            }
            catch (Microsoft.DDSolutions.Tfs.InvalidTfsServerException tfse)
            {
                connecting.Hide();

                MessageBox.Show(tfse.Message, MainResources.InvalidEntryMsg, MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, mbOptions);
            }
            catch (Microsoft.DDSolutions.Tfs.TfsClientServerMismatchException tfscsm)
            {
                connecting.Hide();
                MessageBox.Show(tfscsm.Message, MainResources.ClientServerMistmatchMsg, MessageBoxButtons.OK, MessageBoxIcon.Stop, MessageBoxDefaultButton.Button1, mbOptions);
            }
            catch (XmlException xe)
            {
                connecting.Hide();
                MessageBox.Show(xe.Message, MainResources.InvalidConfigMsg, MessageBoxButtons.OK, MessageBoxIcon.Stop, MessageBoxDefaultButton.Button1, mbOptions);
            }
            catch (System.IO.FileNotFoundException fnfe)
            {
                connecting.Hide();
                MessageBox.Show(fnfe.Message, MainResources.MissingConfigMsg, MessageBoxButtons.OK, MessageBoxIcon.Stop, MessageBoxDefaultButton.Button1, mbOptions);
            }
            catch (System.Net.WebException webEx)
            {
                connecting.Hide();
                MessageBox.Show(MainResources.CouldNotConnectText, webEx.Message, MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, mbOptions);
            }
        }

        /// <summary>
        /// Presents the DomainProjectPicker just as in Team Explorer to select the TFS Server and prompts for
        /// login information if needed.
        /// </summary>
        /// <returns>A TeamFoundationServer object representing the chosen and properly authenticated TFS Server</returns>
        /// <exception cref="Microsoft.DDSolutions.Tfs.InvalidTfsServerException">If the user provides invalid credentials or the user
        /// does not select a TFS Server in which to login this exception is thrown</exception>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        protected TeamFoundationServer ChooseAppServer()
        {
            TeamFoundationServer tfsServer = null;
            DomainProjectPicker dpp = new DomainProjectPicker(DomainProjectPickerMode.None);
            if (dpp.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    TeamFoundationServer tempTfs = new TeamFoundationServer(dpp.SelectedServer.Name, new UICredentialsProvider());
                    tempTfs.Authenticate();
                    tfsServer = tempTfs;
                }
                catch (Microsoft.TeamFoundation.TeamFoundationServerUnauthorizedException unauthException)
                {
                    throw new Microsoft.DDSolutions.Tfs.InvalidTfsServerException(unauthException.Message);
                }
                catch (System.Net.WebException)
                {
                    throw;
                }

            }
            else
            {
                throw new Microsoft.DDSolutions.Tfs.InvalidTfsServerException(MainResources.TFSServerNotSelected);
            }

            return tfsServer;

        }

        /// <summary>
        ///  When the user selects using the select button.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSelect_Click(object sender, EventArgs e)
        {
            if (treeView.SelectedNode != null)
            {
                if (IsProjectSelected())
                {
                    AppController.IsProjectSite = true;
                }
                else
                {
                    AppController.IsProjectSite = false;
                }
                OnSelectNode();
                treeView.Select();
            }
        }
        /// <summary>
        /// Shows the tree view for the chosen server node and the list of team projects
        /// </summary>
        /// <param name="projects"></param>
        private void PopulateTreeView(ReadOnlyCollection<string> projects)
        {
            TreeNode serverNode = new TreeNode(tfsAppServer.Name);
            treeView.Nodes.Add(serverNode);

            foreach (string project in projects)
            {
                serverNode.Nodes.Add(project);
            }
            treeView.Sort();
            treeView.ExpandAll();
        }

        /// <summary>
        ///  When the user refreshes the list of projects.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnRefresh_Click(object sender, EventArgs e)
        {
            lblHelpMessage.Text = MainResources.HelpMessage1;

            MessageBoxOptions mbOptions = new MessageBoxOptions();

            if (this.RightToLeft == RightToLeft.Yes)
                mbOptions = mbOptions | MessageBoxOptions.RtlReading;

            try
            {

                ///Gets a fully authenticated TeamFoundationServer instance

                string projName = string.Empty;
                projName = this.lblLogin.Text.Substring(this.lblLogin.Text.LastIndexOf(" ",StringComparison.Ordinal));
                projName = projName.Trim();
                tfsAppServer = new TeamFoundationServer(projName, new UICredentialsProvider());
                tfsAppServer.Authenticate();

                connecting.Show();
                connecting.Activate();
                Application.DoEvents();

                this.lblLogin.Text = MainResources.LoggedOn + tfsAppServer.Name;

                this.LoginPanel.Visible = false;

                this.toolStripBtnSave.Enabled = false;
                this.toolStripBtnSave.Visible = false;
                this.toolStripBtnUsersGroupsPicker.Enabled = false;
                this.toolStripBtnUsersGroupsPicker.Visible = false;

                this.TeamProjectsPanel.Visible = true;
                this.TeamProjectsPanel.Location = this.LoginPanel.Location;
                this.dataGridView1.Enabled = false;
                this.dataGridView1.Visible = false;
                connecting.Hide();
            }
            catch (Microsoft.DDSolutions.Tfs.InvalidTfsServerException tfse)
            {
                connecting.Hide();

                MessageBox.Show(tfse.Message, MainResources.InvalidEntryMsg, MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, mbOptions);
            }
            catch (Microsoft.DDSolutions.Tfs.TfsClientServerMismatchException tfscsm)
            {
                connecting.Hide();
                MessageBox.Show(tfscsm.Message, MainResources.ClientServerMistmatchMsg, MessageBoxButtons.OK, MessageBoxIcon.Stop, MessageBoxDefaultButton.Button1, mbOptions);
            }
            catch (XmlException xe)
            {
                connecting.Hide();
                MessageBox.Show(xe.Message, MainResources.InvalidConfigMsg, MessageBoxButtons.OK, MessageBoxIcon.Stop, MessageBoxDefaultButton.Button1, mbOptions);
            }
            catch (System.IO.FileNotFoundException fnfe)
            {
                connecting.Hide();
                MessageBox.Show(fnfe.Message, MainResources.MissingConfigMsg, MessageBoxButtons.OK, MessageBoxIcon.Stop, MessageBoxDefaultButton.Button1, mbOptions);
            }
            catch (System.Net.WebException webEx)
            {
                connecting.Hide();
                MessageBox.Show(MainResources.CouldNotConnectText, webEx.Message, MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, mbOptions);
            }
            catch (Microsoft.TeamFoundation.TeamFoundationServerUnauthorizedException unauthException)
            {
                //throw new Microsoft.DDSolutions.Tfs.InvalidTfsServerException(unauthException.Message);
                connecting.Hide();
                MessageBox.Show(MainResources.CouldNotConnectText, unauthException.Message, MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, mbOptions);
            }
            catch (Microsoft.DDSolutions.Tfs.InvalidTfsUserException iue)
            {
                connecting.Hide();
                MessageBox.Show(iue.User, MainResources.InvalidConfigMsg, MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, mbOptions);
            }

        }

        private bool IsProjectSelected()
        {
            return (!treeView.TopNode.IsSelected && treeView.SelectedNode.Text != null);
        }

        /// <summary>
        ///  Helper function to setup and populated the GUI elements when the User selects a team project.
        /// </summary>
        private void OnSelectNode()
        {
            this.Cursor = System.Windows.Forms.Cursors.WaitCursor;

            if (treeView.SelectedNode == null)
                return;

            // Visually highlight the selected TreeNode
            TreeViewUpdateSelection();
            

            string nodeName = treeView.SelectedNode.Text;

            bool spSiteExists = AppController.VerfiySharePointSiteExistance(nodeName);
            bool rsSiteExists = AppController.VerfiyReportingServicesSiteExistance(nodeName);

            if (!spSiteExists || !rsSiteExists)
            {
                string msg = "";

                msg += !spSiteExists ? "SharePoint" : "";
                msg += (!spSiteExists && !rsSiteExists) ? " & " : "";
                msg += !rsSiteExists ? "ReportServer" : "";

                if (MessageBox.Show(string.Format(MainResources.MissingTierConnection, msg), MainResources.MissingTier, MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1) == DialogResult.No)
                {
                    this.Cursor = System.Windows.Forms.Cursors.Default;
                    return;
                }
            }

            //. Since only one item is allowed to be selected. The CheckedItems[0] should be fine.
            dataGridView1.Visible = false;
            dataGridView1.Enabled = false;
            dataGridView1.EditMode = DataGridViewEditMode.EditOnKeystroke;
            toolStripBtnSave.Enabled = true;
            toolStripBtnSave.Visible = true;

            toolStripBtnRefresh.Enabled = true;
            toolStripBtnRefresh.Visible = true;

            toolStripBtnUsersGroupsPicker.Enabled = true;
            toolStripBtnUsersGroupsPicker.Visible = true;

            connecting.CaptionText = MainResources.SplashMessage1;
            connecting.Show();
            connecting.Activate();
            Application.DoEvents();


            actionLog.Tables[0].Rows.Clear();
            actionLog.Tables["AllTransactions"].Rows.Clear();

            try
            {
                //Added the call to the AppController.PrepRoleConfig to parse the RoleConfig.xml file at this point. 
                //Prior to this it was in the AppController as part of the OnTfsLogin method. This was
                //too early in the process as team project had been selected and thus the team project
                //SharePoint site could not be connected to and evaluated to determine if WSS 3.0
                AppController.PrepRoleConfig(nodeName);
              
                actionLogDataGridView.DataSource = actionLog;
                actionLogDataGridView.DataMember = "ActionLog";
                connecting.Hide();

                this.Cursor = System.Windows.Forms.Cursors.WaitCursor;
                connecting.CaptionText = MainResources.SplashMessage2;
                connecting.Show();
                Application.DoEvents();

                SetupTfsRoles(nodeName);
                SetupSharePointRoles(nodeName);
                SetupReportingServicesRoles(nodeName);

                this.RefreshDataGrid();
                connecting.Hide();
                lblHelpMessage.Text = MainResources.HelpMessage3;

            }
            catch (Microsoft.DDSolutions.SharePoint.InvalidSPServerException spe)
            {
                MessageBoxOptions mboptions = MessageBoxOptions.RightAlign;
                connecting.Hide();
                if (this.RightToLeft == RightToLeft.Yes)
                    MessageBox.Show(spe.Message, MainResources.InvalidServerMsg, MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, mboptions | MessageBoxOptions.RtlReading);
                else
                    MessageBox.Show(spe.Message, MainResources.InvalidServerMsg, MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, mboptions);
                dataGridView1.Visible = false;
                this.Cursor = System.Windows.Forms.Cursors.Default;
            }
            catch (System.Net.WebException we)
            {
                MessageBoxOptions mboptions = MessageBoxOptions.RightAlign;
                connecting.Hide();
                if (this.RightToLeft == RightToLeft.Yes)
                    MessageBox.Show(we.Message, MainResources.UnableToAccessMsg, MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, mboptions | MessageBoxOptions.RtlReading);
                else
                    MessageBox.Show(we.Message, MainResources.UnableToAccessMsg, MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, mboptions);
                dataGridView1.Visible = false;
                this.Cursor = System.Windows.Forms.Cursors.Default;
            }
            catch (System.Web.Services.Protocols.SoapException ex)
            {
                MessageBoxOptions mboptions = MessageBoxOptions.RightAlign;
                connecting.Hide();
                if (this.RightToLeft == RightToLeft.Yes)
                    MessageBox.Show(ex.Message, MainResources.InsufficientPermissionsText, MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, mboptions | MessageBoxOptions.RtlReading);
                else
                    MessageBox.Show(ex.Message, MainResources.InsufficientPermissionsText, MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, mboptions);
                dataGridView1.Visible = false;
                this.Cursor = System.Windows.Forms.Cursors.Default;
            }
        }

        private void SetupTfsRoles(string nodeName)
        {
          //supporting multiple tfs roles so make it a check list
          Microsoft.DDSolutions.UI.CheckBoxComboColumn TfsRolesCol = (Microsoft.DDSolutions.UI.CheckBoxComboColumn)this.dataGridView1.Columns["TFSRole"];
          ReadOnlyCollection<string> tfsRoles = AppController.GetTfsRoles(nodeName);
          TfsRolesCol.Clear();
          foreach (string itm in tfsRoles)
            TfsRolesCol.AddItem(itm);
        }

        private void SetupSharePointRoles(string nodeName)
        {
            // If site doesn't exist skip role setup and disable sharepoint column in the grid
            if (!AppController.VerfiySharePointSiteExistance(nodeName))
            {
                dataGridView1.Columns[4].ReadOnly = true;
                return;
            }
            else
            {
                dataGridView1.Columns[4].ReadOnly = false;
            }

            ReadOnlyCollection<string> invalidSPRoles = AppController.GetInvalidRolesFromMappings(nodeName, "SharePoint");

            if (invalidSPRoles != null && invalidSPRoles.Count > 0)
            {
                foreach (string spRole in invalidSPRoles)
                {
                    AddLogRecord(MainResources.strLogValidate,
                                 MainResources.strLogSystem,
                                 "",
                                 MainResources.strSPShortName,
                                 spRole,
                                 MainResources.strLogFailed,
                                 MainResources.RoleDoesntExistMsg);
                }
            }

            Microsoft.DDSolutions.UI.CheckBoxComboColumn SpRolesCol = (Microsoft.DDSolutions.UI.CheckBoxComboColumn)this.dataGridView1.Columns["SPRoles"];
            ReadOnlyCollection<string> spRoles = AppController.GetSharePointRoles(nodeName);
            SpRolesCol.Clear();
            foreach (string itm in spRoles)
                SpRolesCol.AddItem(itm);
        }

        private void SetupReportingServicesRoles(string nodeName)
        {
          // If site doesn't exist skip role setup and disable sharepoint column in the grid
          if (!AppController.VerfiyReportingServicesSiteExistance(nodeName))
          {
              dataGridView1.Columns[5].ReadOnly = true;
              return;
          }
          else
          {
              dataGridView1.Columns[5].ReadOnly = false;
          }

          ReadOnlyCollection<string> invalidRSRoles = AppController.GetInvalidRolesFromMappings(nodeName, "ReportServer");

          if (invalidRSRoles != null && invalidRSRoles.Count > 0)
          {
            foreach (string rsRole in invalidRSRoles)
            {
              AddLogRecord(MainResources.strLogValidate,
                  MainResources.strLogSystem,
                  "",
                  MainResources.strRSShortName,
                  rsRole,
                  MainResources.strLogFailed,
                  MainResources.RoleDoesntExistMsg);
            }
          }

          Microsoft.DDSolutions.UI.CheckBoxComboColumn RsRolesCol = (Microsoft.DDSolutions.UI.CheckBoxComboColumn)this.dataGridView1.Columns["RSRoles"];
          ReadOnlyCollection<string> rsRoles = AppController.GetReportingServicesRoles();
          RsRolesCol.Clear();
          foreach (string itm in rsRoles)
            RsRolesCol.AddItem(itm);
        }

        private void TreeViewUpdateSelection()
        {
            treeView.BeginUpdate();
            if (selectedNode != null)
            {
                selectedNode.NodeFont = defaultFont;
            }

            // highlight the selected node
            treeView.SelectedNode.NodeFont = selectedFont;
            treeView.Refresh();
            treeView.EndUpdate();

            selectedNode = treeView.SelectedNode;
        }

        private void SetupDataGridViewColumns()
        {
            dataGridView1.AutoGenerateColumns = false;
            dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
            dataGridView1.MultiSelect = false;

            // Set the column header style.
            DataGridViewCellStyle columnHeaderStyle =
                new DataGridViewCellStyle();
            columnHeaderStyle.BackColor = Color.FromArgb(237, 243, 254);
            columnHeaderStyle.Font =
                new Font("Microsoft Sans Serif", 10, FontStyle.Bold);
            dataGridView1.ColumnHeadersDefaultCellStyle =
                columnHeaderStyle;

            DataGridViewImageColumn imageColumn = new DataGridViewImageColumn();
            //Add twice the padding for the left and 
            //right sides of the cell.
            imageColumn.Width = userIcon.Width + 2 * bitmapPadding + 1;
            imageColumn.Name = "Status";
            imageColumn.HeaderText = String.Empty;
            imageColumn.ValuesAreIcons = true;
            imageColumn.Icon = userIcon;
            imageColumn.DataPropertyName = "Status";

            DataGridViewTextBoxColumn col1 = new DataGridViewTextBoxColumn();
            col1.Name = "User";
            col1.HeaderText = MainResources.UserColumnHeaderText;
            col1.DataPropertyName = "User";

            DataGridViewTextBoxColumn col11 = new DataGridViewTextBoxColumn();
            col11.Name = "DisplayName";
            col11.ReadOnly = true;
            col11.HeaderText = MainResources.DisplayNameColumnHeaderText;
            col11.DataPropertyName = "DisplayName";

            Microsoft.DDSolutions.UI.CheckBoxComboColumn col2 = new Microsoft.DDSolutions.UI.CheckBoxComboColumn();
            col2.Name = "TFSRole";
            col2.HeaderText = MainResources.TFSRoleColumnHeaderText;
            col2.DataPropertyName = "TFSRole";
           

            Microsoft.DDSolutions.UI.CheckBoxComboColumn col3 = new Microsoft.DDSolutions.UI.CheckBoxComboColumn();
            col3.Name = "SPRoles";
            col3.HeaderText = MainResources.SPRoleColumnHeaderText;
            col3.DataPropertyName = "SPRoles";


            Microsoft.DDSolutions.UI.CheckBoxComboColumn col4 = new Microsoft.DDSolutions.UI.CheckBoxComboColumn();
            col4.Name = "RSRoles";
            col4.HeaderText = MainResources.RSRoleColumnHeaderText;
            col4.DataPropertyName = "RSRoles";


            DataGridViewCheckBoxColumn deleteCol = new DataGridViewCheckBoxColumn();
            deleteCol.Name = "MarkDelete";
            deleteCol.HeaderText = MainResources.strMarkForDelete;
            deleteCol.ValueType = System.Type.GetType("System.Boolean");
            DataGridViewCheckBoxCell markDelete =
                    (DataGridViewCheckBoxCell)deleteCol.CellTemplate;

            markDelete.TrueValue = true;
            markDelete.FalseValue = false;
            deleteCol.DataPropertyName = "MarkDelete";

            this.dataGridView1.Columns.Insert(0, imageColumn); // Status
            this.dataGridView1.Columns.Insert(1, col1);        // User
            this.dataGridView1.Columns.Insert(2, col11);       // DisplayName
            this.dataGridView1.Columns.Insert(3, col2);        // TFS Role
            this.dataGridView1.Columns.Insert(4, col3);        // SP Role
            this.dataGridView1.Columns.Insert(5, col4);        // RS Role
            this.dataGridView1.Columns.Insert(6, deleteCol);   // Mark User for Deletion.

            col2.AddedOrDeletedRole += new EventHandler<Microsoft.DDSolutions.UI.AddedOrDeletedRoleEventArgs>(col3_AddedOrDeletedRole);
            col3.AddedOrDeletedRole += new EventHandler<Microsoft.DDSolutions.UI.AddedOrDeletedRoleEventArgs>(col3_AddedOrDeletedRole);
            col4.AddedOrDeletedRole += new EventHandler<Microsoft.DDSolutions.UI.AddedOrDeletedRoleEventArgs>(col3_AddedOrDeletedRole);

            this.dataGridView1.CellValueChanged += new DataGridViewCellEventHandler(dataGridView1_CellValueChanged);
            this.dataGridView1.CurrentCellDirtyStateChanged += new EventHandler(dataGridView1_CurrentCellDirtyStateChanged);
            this.dataGridView1.CellValueNeeded += new DataGridViewCellValueEventHandler(dataGridView1_CellValueNeeded);

            this.dataGridView1.DefaultValuesNeeded += new DataGridViewRowEventHandler(dataGridView1_DefaultValuesNeeded);
            this.dataGridView1.CellClick += new DataGridViewCellEventHandler(dataGridView1_CellClick);
            this.dataGridView1.CellFormatting += new DataGridViewCellFormattingEventHandler(dataGridView1_CellFormatting);
            this.dataGridView1.CellValidating += new DataGridViewCellValidatingEventHandler(dataGridView1_CellValidating);
            this.dataGridView1.CellEndEdit += new DataGridViewCellEventHandler(dataGridView1_CellEndEdit);
            this.dataGridView1.CellBeginEdit += new DataGridViewCellCancelEventHandler(dataGridView1_CellBeginEdit);
        }

        void dataGridView1_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
        {
            if (String.Compare(dataGridView1.Columns[e.ColumnIndex].Name, "User", StringComparison.CurrentCultureIgnoreCase) == 0)
            {
                string userName = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString();

                if (String.IsNullOrEmpty(userName) == false &&
                    String.Compare(this.dataGridView1.Rows[e.RowIndex].Cells[0].Value.ToString(), "A",StringComparison.Ordinal) != 0)
                {
                    e.Cancel = true;
                    dataGridView1.Rows[e.RowIndex].ErrorText = MainResources.CannotEditUserName;
                }

            }
        }

        void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            if (String.Compare(dataGridView1.Columns[e.ColumnIndex].Name, "User", StringComparison.CurrentCultureIgnoreCase) == 0)
            {
                dataGridView1.Rows[e.RowIndex].ErrorText = string.Empty;
                string userName = dataGridView1.Rows[e.RowIndex].Cells["User"].FormattedValue.ToString().Trim();
                if (string.IsNullOrEmpty(userName) == true)
                {
                    return;
                }
                string dispName = AppController.GetFriendlyDisplayName(userName);
                dataGridView1.Rows[e.RowIndex].Cells["DisplayName"].Value = dispName;
                ds.Tables[0].AcceptChanges();
            }

        }


        void dataGridView1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
        {
            if (dataGridView1.Enabled == false)
                return;
            if (ignoreEdit == true)
            {
                ignoreEdit = false;
                return;
            }

            if (String.Compare(dataGridView1.Columns[e.ColumnIndex].Name, "User", StringComparison.CurrentCultureIgnoreCase) == 0)
            {
                dataGridView1.Rows[e.RowIndex].ErrorText = string.Empty;

                //. Don't try to valid new row until finished
                if (dataGridView1.Rows[e.RowIndex].IsNewRow) { return; }


                if (String.IsNullOrEmpty(e.FormattedValue.ToString().Trim()) == true)
                {
                    e.Cancel = true;
                    if (!string.Equals(dataGridView1.Rows[e.RowIndex].Cells["Status"].Value.ToString(), "A"))
                    {
                        dataGridView1.Rows[e.RowIndex].ErrorText = MainResources.InvalidUserNameEntry;
                    }
                }
                else
                {
                    if (e.FormattedValue.ToString().Trim().Split('\\').Length < 2)
                    {
                        e.Cancel = true;
                        dataGridView1.Rows[e.RowIndex].ErrorText = MainResources.InvalidEntryMsg;
                        return;
                    }

                    // Check if the username is a valid domain user name by getting its
                    // display name.
                    string dispName = AppController.GetFriendlyDisplayName(e.FormattedValue.ToString().Trim());

                    // Explicity checking only for null. If the users had not set the display name on the 
                    // windows machine it would be empty.
                    if (dispName == null)
                    {
                        e.Cancel = true;
                        dataGridView1.Rows[e.RowIndex].ErrorText = MainResources.InvalidEntryMsg;
                        return;
                    }

                    string user = e.FormattedValue.ToString().Trim();
                    DataRow row = ds.Tables[0].Rows.Find(new object[] { user });

                    DataRowView drv = (DataRowView)this.dataGridView1.Rows[e.RowIndex].DataBoundItem;

                    //. If row exist then the user already exist.
                    if (row != null &&
                        String.Compare(this.dataGridView1.Rows[e.RowIndex].Cells[0].Value.ToString(), "A", StringComparison.Ordinal) == 0 &&
                        drv.Row.Equals(row) == false)
                    {

                        e.Cancel = true;
                        dataGridView1.Rows[e.RowIndex].ErrorText = MainResources.UserAlreadyExist;
                    }
                    else
                        e.Cancel = false;
                }
            }
        }

        void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {
            if (e.ColumnIndex < 0)
                return;

            if (this.dataGridView1.Columns[e.ColumnIndex].Name == "Status")
            {
                string statusValue = e.Value as string;

                //. For last row the status value would be null.
                //. replace it with a new user Icon.
                if (statusValue == null)
                {
                    e.Value = newuserIcon;
                    return;
                }

                //. Since the enum value is a char just use the first char here
                UserEditStatus StatusEnum = (UserEditStatus)statusValue[0];

                switch (StatusEnum)
                {
                    case UserEditStatus.Initial:
                        e.Value = userIcon;
                        break;
                    case UserEditStatus.Add:
                        e.Value = adduserIcon;
                        break;
                    case UserEditStatus.Delete:
                        e.Value = removeuserIcon;
                        break;
                    case UserEditStatus.Change:
                        e.Value = modifyuserIcon;
                        break;
                    case UserEditStatus.Error:
                        e.Value = erroruserIcon;
                        break;
                }
            }
        }

        void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            DataSet dsfiltered = new DataSet();
            dsfiltered.Locale = CultureInfo.CurrentUICulture;
            if (e.ColumnIndex == 0)
            {
                string user = this.dataGridView1.Rows[e.RowIndex].Cells["User"].Value.ToString();
                string filter = "User='" + user + "'";

                DataTable filteredData = actionLog.Tables["AllTransactions"].Clone();
                DataRow[] dr = actionLog.Tables["AllTransactions"].Select(filter);

                filteredData.TableName = "AllTransactions";

                foreach (DataRow drow in dr)
                {
                    DataRow newRow = filteredData.NewRow();

                    newRow["User"] = drow["User"];
                    newRow["DisplayName"] = drow["DisplayName"];
                    newRow["Action"] = drow["Action"];
                    newRow["Tier"] = drow["Tier"];
                    newRow["Role"] = drow["Role"];
                    newRow["State"] = drow["State"];
                    filteredData.Rows.Add(newRow);
                }

                dsfiltered.Tables.Add(filteredData);
                dsfiltered.AcceptChanges();

                UserChangeLog viewChangeDetails = new UserChangeLog();
                viewChangeDetails.DataSource = dsfiltered;
                viewChangeDetails.DataMember = "AllTransactions";
                viewChangeDetails.ShowDialog();
            }
        }

        /// <summary>
        ///   Whenever the Cell Value of the DataGridView changes the following is invoked.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            /// When the user changes the TFS role for a given user we need to populate the 
            /// appropriate roles in the SharePoint and ReportingService roles based on 
            /// default mapping. Also note that for existing TFS users we need to delete
            /// all their current roles and re-create them with new roles.
            if (String.Compare(this.dataGridView1.Columns[e.ColumnIndex].Name, "TFSRole", true, CultureInfo.CurrentUICulture) == 0)
            {
                string tfsRole = this.dataGridView1.Rows[e.RowIndex].Cells["TFSRole"].Value.ToString();
                string tfsUser = this.dataGridView1.Rows[e.RowIndex].Cells["User"].Value.ToString();
                string displayName = this.dataGridView1.Rows[e.RowIndex].Cells["DisplayName"].Value.ToString();

                AddTransaction("Deleted", tfsUser, displayName, "TFS", "All");
                AddTransaction("Added", tfsUser, displayName, "TFS", tfsRole);

                string tfsMappedRoles = AppController.GetMappedRoleStringBySystem(tfsRole, "Tfs");
                string spMappedRoles = AppController.GetMappedRoleStringBySystem(tfsRole, "SharePoint");
                string rsMappedRoles = AppController.GetMappedRoleStringBySystem(tfsRole, "ReportServer");

                if (String.IsNullOrEmpty(tfsMappedRoles) == false)
                {
                    this.dataGridView1.Rows[e.RowIndex].Cells["TFSRole"].Value = tfsMappedRoles;
                    /// Add the mapped roles to SP and RS
                    foreach (string spRole in tfsMappedRoles.Split(';'))
                    {
                        AddTransaction("Added", tfsUser, displayName, "TFS", spRole);
                    }
                }

                /// Set the Mapped Roles to SP and RS
                if (String.IsNullOrEmpty(spMappedRoles) == false)
                {
                    this.dataGridView1.Rows[e.RowIndex].Cells["SPRoles"].Value = spMappedRoles;
                    /// Add the mapped roles to SP and RS
                    foreach (string spRole in spMappedRoles.Split(';'))
                    {
                        AddTransaction("Added", tfsUser, displayName, "SP", spRole);
                    }
                }

                if (String.IsNullOrEmpty(rsMappedRoles) == false)
                {
                    this.dataGridView1.Rows[e.RowIndex].Cells["RSRoles"].Value = rsMappedRoles;

                    foreach (string rsRole in rsMappedRoles.Split(';'))
                    {
                        AddTransaction("Added", tfsUser, displayName, "RS", rsRole);
                    }
                }
                //. Since the TFS role has changed mark the Icon as modified, but only in case where its not a newly
                //. added record.
                if (String.Compare(this.dataGridView1.Rows[e.RowIndex].Cells[0].Value.ToString(), "A", StringComparison.Ordinal) != 0)
                    this.dataGridView1.Rows[e.RowIndex].Cells[0].Value = "C";
            }
            else if (e.ColumnIndex == 6)
            {
                DataGridViewCheckBoxCell cbCell = (DataGridViewCheckBoxCell)this.dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex];
                if (cbCell.Value.Equals(cbCell.FalseValue))
                    this.dataGridView1.Rows[e.RowIndex].Cells[0].Value = "I";
                else
                    this.dataGridView1.Rows[e.RowIndex].Cells[0].Value = "D";
            }
        }

        // This event handler manually raises the CellValueChanged event
        // by calling the CommitEdit method.
        void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
        {
            if (dataGridView1.IsCurrentCellDirty &&
                (dataGridView1.CurrentCell.ColumnIndex == 6 ||
                   dataGridView1.CurrentCell.ColumnIndex == 0 ||
                   dataGridView1.CurrentCell.ColumnIndex == 1))
            {
                dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
            }
        }

        /// <summary>
        ///   Handle a AddedorDeletedRole by user event.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void col3_AddedOrDeletedRole(object sender, Microsoft.DDSolutions.UI.AddedOrDeletedRoleEventArgs e)
        {
            string tier = "";
            string action = "";

            if (e == null)
                throw new ArgumentNullException(MainResources.RoleAddedEventExceptionMsg);

            if (e == Microsoft.DDSolutions.UI.AddedOrDeletedRoleEventArgs.Empty)
                throw new ArgumentException(MainResources.RoleAddedEventExceptionMsg);

            if (e.Tier == Microsoft.DDSolutions.UI.SystemTier.Tfs)
                tier = "TFS";
            else if (e.Tier == Microsoft.DDSolutions.UI.SystemTier.SharePoint)
                tier = "SP";
            else if (e.Tier == Microsoft.DDSolutions.UI.SystemTier.ReportServer)
                tier = "RS";

            if (e.ItemState == Microsoft.DDSolutions.UI.ItemState.Added)
                action = "Added";
            else if (e.ItemState == Microsoft.DDSolutions.UI.ItemState.Deleted)
                action = "Deleted";

            //. Change the Status Image Column to denote change.
            this.dataGridView1.Rows[e.CurrentRow].Cells[0].Value = "C";

            /// Add a transaction to our transaction cache in dataset ds.
            AddTransaction(action, e.User, e.DisplayName, tier, e.Role);
        }

        /// <summary>
        ///   Repaint the cell background to RED in case no Roles as assigned to the user in these sub systems.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dataGridView1_CellPainting(object sender, System.Windows.Forms.DataGridViewCellPaintingEventArgs e)
        {
            if ((this.dataGridView1.Columns["SPRoles"].Index == e.ColumnIndex ||
                this.dataGridView1.Columns["RSRoles"].Index == e.ColumnIndex) && e.RowIndex >= 0)
            {
                /// Empty row at the bottom meant for New record addition.
                /// This should not be changed to red background.
                if (e.RowIndex >= numberOfRows - 1)
                    return;

                /// If row contains no selection of tfs roles we will consider it to be
                /// incomplete and thus we will leave out the coloring of the SP & RS columns.
                /// This should do the trick for both disable and incomplete coloring.
                if (String.IsNullOrEmpty(this.dataGridView1.Rows[e.RowIndex].Cells[this.dataGridView1.Columns["TFSRole"].Index].EditedFormattedValue.ToString()) == true)
                    return;
              
                //. If column is disabled this means the underlying site is missing and
                //. therefore we set the backgound to grey
                if (this.dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].ReadOnly == true)
                {
                  Brush backColorBrush = new SolidBrush(Color.Gray);
                  e.Graphics.FillRectangle(backColorBrush, e.CellBounds);

                  e.Handled = true;
                }
                else
                {
                  //. Else if its blank then turn background to Red.
                  if (String.IsNullOrEmpty(this.dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].EditedFormattedValue.ToString()) == true)
                  {
                    Brush backColorBrush = new SolidBrush(Color.Red);
                    e.Graphics.FillRectangle(backColorBrush, e.CellBounds);

                    e.Handled = true;
                  }
                }
            }
        }

        private void dataGridView1_CancelRowEdit(object sender, System.Windows.Forms.QuestionEventArgs e)
        {
          if ((numberOfRows - 1) >= this.dataGridView1.CurrentCell.RowIndex)
            numberOfRows -= 1;

          /// TODO: We need to restore the values of the cells
          /// TODO: We need to change the Icon of the row to the User Icon
          /// The above is important if the row contains edits in other cells as well
          
          /// Since the RowEdit has been cancelled we need to 
          /// roll back all the edits for the selected user.             
          DeleteTransactions(this.dataGridView1.CurrentRow.Cells[1].Value.ToString());
          
          e.Response = true;
          dataGridView1.Rows[this.dataGridView1.CurrentCell.RowIndex].ErrorText = string.Empty;
        }

        private void dataGridView1_NewRowNeeded(object sender, DataGridViewRowEventArgs e)
        {
            newRowNeeded = true;
        }

        private void dataGridView1_DefaultValuesNeeded(object sender, DataGridViewRowEventArgs e)
        {
            e.Row.Cells["Status"].Value = "A";
            e.Row.Cells["User"].Value = String.Empty;
        }



        private void dataGridView1_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
        {

            if (newRowNeeded)
            {
                newRowNeeded = false;
                startTransaction = actionLog.Tables["AllTransactions"].Rows.Count;
                numberOfRows = numberOfRows + 1;
            }

        }


        void dataGridView1_UserDeletingRow(object sender, System.Windows.Forms.DataGridViewRowCancelEventArgs e)
        {
            numberOfRows = numberOfRows - 1;

            DataGridViewCheckBoxCell markDelete =
                        (DataGridViewCheckBoxCell)dataGridView1.Rows[e.Row.Index].Cells[MainResources.strMarkDelete];

            markDelete.Value = markDelete.TrueValue;

            this.dataGridView1.Rows[e.Row.Index].Cells[0].Value = "D";

            e.Cancel = true;
            RefreshDataGrid();
        }



        private void dataGridView1_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
        {
            if (newRowNeeded && e.RowIndex == numberOfRows)
            {

                if (dataGridView1.Columns[e.ColumnIndex].Name == MainResources.strMarkForDelete)
                {
                    e.Value = false;
                }
                else if (!dataGridView1.IsCurrentCellInEditMode && e.ColumnIndex != 0)
                {
                    // Show a blank value if the cursor is just resting
                    // on the last row.
                    e.Value = String.Empty;
                }
                else if (e.ColumnIndex == 0)
                {
                    e.Value = "A";
                }
            }
            else if (e.ColumnIndex == 0)
            {
                e.Value = "I";
            }

        }



        private void actionLogDataGridView_CellPainting(object sender, System.Windows.Forms.DataGridViewCellPaintingEventArgs e)
        {
            if (this.actionLogDataGridView.Columns["Status"].Index ==
                e.ColumnIndex && e.RowIndex >= 0)
            {
                //. Action column value 
                //. If its blank then turn background to Red.
                if (this.actionLogDataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].EditedFormattedValue.ToString() == MainResources.strLogFailed)
                {
                    Brush backColorBrush = new SolidBrush(Color.Red);
                    e.Graphics.FillRectangle(backColorBrush, e.CellBounds);
                    e.Graphics.DrawRectangle(new Pen(Color.White, 1), e.CellBounds);
                    e.Graphics.DrawString(MainResources.strLogFailed, new Font("Veranda", 10), new SolidBrush(Color.White), e.CellBounds);
                    e.Handled = true;
                }

            }
        }

        /// <summary>
        /// OnSave
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolStripBtnSave_Click(object sender, EventArgs e)
        {
            bool actionFailed = false;

            if (connecting.Visible == true)
                return;

            connecting.CaptionText = MainResources.SplashMessage3;
            connecting.Show();
            Application.DoEvents();

            string errMsg = "";
            string nodeName = treeView.SelectedNode.Text;

            ds.Tables[0].AcceptChanges();
            this.dataGridView1.EndEdit();

            DeleteUsersMarkedForDeletetion();

            foreach (DataRow r in actionLog.Tables["AllTransactions"].Rows)
            {
                string user = r["User"].ToString();
                string displayName = r["DisplayName"].ToString();
                string role = r["Role"].ToString();
                string action = r["Action"].ToString();
                string tier = r["Tier"].ToString();
                actionFailed = false;


                //. Execute Actions.
                try
                {
                    if (action == "Added")
                    {
                        if (tier == "SP")
                            AppController.AddSharePointUserToRole(user, role, nodeName);
                        else if (tier == "RS")
                            AppController.AddUserToReportServer(user, role, nodeName);
                        else if (tier == "TFS")
                            AppController.AddUserToTfsRole(user, role, nodeName);
                    }
                    else if (action == "Deleted")
                    {
                        if (tier == "SP")
                            AppController.RemoveSharePointUserFromRole(user, role, nodeName);
                        else if (tier == "RS")
                            AppController.RemoveUserFromReportServer(user, role, nodeName);
                        else if (tier == "TFS" && role == "All")
                            AppController.RemoveTFSUser(user, nodeName);
                    }
                }
                catch (Microsoft.DDSolutions.Tfs.InvalidTfsUserException tfse)
                {
                    actionFailed = true;
                    errMsg = tfse.Message;
                }
                catch (System.Web.Services.Protocols.SoapException se)
                {
                    actionFailed = true;
                    errMsg = se.Message;
                }
                catch (System.ArgumentNullException exc)
                {
                    actionFailed = true;
                    errMsg = exc.Message;
                }
                //. Update ActionLog Grid dataset table.

                if (actionFailed == true)
                {
                    // If this is the first time the user is being added to TFS he won't have
                    // any role before and hence the failure to delete him should be ignored.
                    if (tier.Equals("TFS") == false && role.Equals("All") == false)
                        AddLogRecord(action, user, displayName, tier, role, MainResources.strLogFailed, errMsg);

                    // Update the status of the transaction.
                    r["State"] = "Failed";
                    if (string.IsNullOrEmpty(user) == false)
                        SetUserEditStatus(user, UserEditStatus.Error);

                }
                else if (role == "All")
                {
                    AddLogRecord(action, user, displayName, tier, role, MainResources.strLogPassed, MainResources.TfsUserDeletedMsg);
                    SetUserEditStatus(user, UserEditStatus.Initial);
                }
                else
                {
                    AddLogRecord(action, user, displayName, tier, role, MainResources.strLogPassed, " ");
                    SetUserEditStatus(user, UserEditStatus.Initial);
                }
            }

            ds.Tables[0].AcceptChanges();
            int maxRecords = actionLog.Tables["AllTransactions"].Rows.Count;
            int rowIndex = 0;

            DataRowCollection drc = actionLog.Tables["AllTransactions"].Rows;
            while (rowIndex < maxRecords)
            {
                DataRow dr = drc[rowIndex];
                if (String.Compare(dr["State"].ToString(), "Failed", true,CultureInfo.CurrentUICulture) != 0)
                {
                    dr.Delete();
                    actionLog.Tables["AllTransactions"].AcceptChanges();
                    maxRecords--;
                }
                else
                    rowIndex++;
            }

            connecting.Hide();
        }

        private void toolStripBtnUsersGroupsPicker_Click(object sender, EventArgs e)
        {
        
            Dictionary<string,string> usersGroupsCollection = AppController.ShowAddGroupControl(this, tfsAppServer);
            
            if (usersGroupsCollection == null)
                return;
            
            foreach (KeyValuePair<string,string> kvp in usersGroupsCollection)
            {
                InsertIntoDataGrid(kvp.Key, kvp.Value);
            }
        }

        private void InsertIntoDataGrid(string user, string displayName)
        {
            DataRow duplicateRow = ds.Tables[0].Rows.Find(user);
            if (duplicateRow != null)
            {
                return;
            }

            if (IsNewRowNeeded())
            {
                DataRow row = ds.Tables[0].NewRow ();
                row["User"] = user;
                row["DisplayName"] = displayName;
                row["Status"] = "A";
                ds.Tables[0].Rows.Add(row);

                if (numberOfRows <= dataGridView1.Rows.Count)
                {
                    dataGridView1.CurrentRow.Selected = false;
                    dataGridView1.Rows[numberOfRows - 1].Selected = true;

                    dataGridView1.CurrentCell.Selected = false;
                    dataGridView1.Rows[numberOfRows - 1].Cells[4].Selected = true;
                }
            }
            else
            {
                DataGridViewRow row = dataGridView1.CurrentRow;
                row.Cells["User"].Value = user;
                row.Cells["DisplayName"].Value = displayName;
                row.Cells["Status"].Value = "A";
                
                dataGridView1.CurrentCell = dataGridView1[4, dataGridView1.CurrentRow.Index];
            }
        }
        private bool IsNewRowNeeded()
        {
            if (dataGridView1.CurrentRow == null)
            {
                return true;
            }
            else
            {
                return !(string.IsNullOrEmpty(dataGridView1.CurrentRow.Cells["User"].Value.ToString())
                    && string.IsNullOrEmpty(dataGridView1.CurrentRow.Cells["DisplayName"].Value.ToString()));
            }
        }

        private void SetUserEditStatus(string user, UserEditStatus status)
        {
            if (String.IsNullOrEmpty(user))
                throw new ArgumentNullException(MainResources.UserText);


            //. Get the corresponding DataRow from the DataGridView dataset that display all users and their permissions.
            DataRow row = ds.Tables[0].Rows.Find(new object[] { user });

            //. This is to update the status column image in case of failure.
            if (row != null)
            {
                row["Status"] = status.ToString()[0];
            }
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1817:DoNotCallPropertiesThatCloneValuesInLoops")]
        private void DeleteUsersMarkedForDeletetion()
        {
            bool deleteUser = false;
            int maxRecords = dataGridView1.Rows.Count;
            int rowIndex = 0;

            DataGridViewRowCollection dgvrc = dataGridView1.Rows;

            while(rowIndex < maxRecords)
            {
                deleteUser = false;
                DataGridViewRow dr = dgvrc[rowIndex];

                // Just an additional check
                if (dr == null)
                    break;

                if (dr.IsNewRow == true)
                    break;

                DataGridViewCheckBoxCell markDelete =
                        (DataGridViewCheckBoxCell)dr.Cells[MainResources.strMarkDelete];

                if (markDelete.Value != System.DBNull.Value && markDelete.Value != null)
                    deleteUser = (Boolean)markDelete.Value;

                if (deleteUser == true)
                {
                    string tfsUser = dr.Cells["User"].Value.ToString();
                    string displayName = dr.Cells["DisplayName"].Value.ToString();

                    if (String.IsNullOrEmpty(tfsUser) == true)
                        return;

                    AddTransaction("Deleted", tfsUser, displayName, MainResources.strTFSShortName, "All");

                    DataRow row = ds.Tables[0].Rows.Find(new object[] { tfsUser });
                    if (row == null)
                        break;

                    row.Delete();
                    ds.Tables[0].AcceptChanges();

                    maxRecords--;


                    // Since deleting the row moves the record up one row the Icon needs to be reset.
                    this.dataGridView1.Rows[rowIndex].Cells[0].Value = "I";
                }
                else
                    rowIndex++;
            }

            numberOfRows = maxRecords;
        }

        private void RefreshDataGrid()
        {
           
            string nodeName = treeView.SelectedNode.Text;
            
            ds = AppController.GetDataSet(nodeName);

            //. If you are half way through edit then discard that as the user hit refresh.
            this.dataGridView1.CancelEdit();

            numberOfRows = this.dataGridView1.Rows.Count;
            this.Cursor = System.Windows.Forms.Cursors.Default;

            dataGridView1.DataSource = ds;
            dataGridView1.DataMember = "TfsUserAndRoles";
            numberOfRows = this.dataGridView1.Rows.Count;

            dataGridView1.Visible = true;
            dataGridView1.Enabled = true;
            dataGridView1.AutoResizeColumns();
            dataGridView1.Focus();
        }

        private void AddTransaction(string action, string user, string displayName, string tier, string role)
        {
            DataRow row = actionLog.Tables["AllTransactions"].NewRow();
            row["User"] = user;
            row["DisplayName"] = displayName;
            row["Action"] = action;
            row["Role"] = role;
            row["Tier"] = tier;
            row["State"] = "Added";
            actionLog.Tables["AllTransactions"].Rows.Add(row);
        }

        /// <summary>
        /// Deletes all transactions for a particular user
        /// </summary>
        /// <param name="user"></param>
        private void DeleteTransactions(string user)
        {
          int rowIndex = 0;

          while (rowIndex < actionLog.Tables["AllTransactions"].Rows.Count)
          {
            if (actionLog.Tables["AllTransactions"].Rows[rowIndex][1].ToString() == user)
            {
              actionLog.Tables["AllTransactions"].Rows[rowIndex].Delete();
            }
            else
            {
              rowIndex++;
            }
          }
        }

        private void AddLogRecord(string action,string user,string displayName, string tier, string role, string status, string comments)
        {

            DataRow row = this.actionLog.Tables[0].NewRow();
            row["Action"] = action;
            row["User"] = user;
            row["DisplayName"] = displayName;
            row["Tier"] = tier;
            row["Role"] = role;
            row["Status"] = status;
            row["Comments"] = comments;

            actionLog.Tables[0].Rows.Add(row);
        }

        private void toolStripBtnRefresh_Click(object sender, EventArgs e)
        {
            ignoreEdit = true; //we need to ignore validating the row when the user refreshes 
            connecting.CaptionText = MainResources.RefreshSplashMessage;
            connecting.Show();
            Application.DoEvents();

            this.RefreshDataGrid();

            connecting.Hide();
        }

        private void aboutButton_Click(object sender, EventArgs e)
        {
            About aboutBox = new About();
            aboutBox.ShowDialog();
        }

        private void btnDisconnect_Click(object sender, EventArgs e)
        {
            //If we have any uncommited transactions we need to display a warning message
            if (actionLog.Tables["AllTransactions"].Rows.Count > 0)
            {
                DialogResult result = MessageBox.Show(MainResources.DisconnectDialogTxt, MainResources.DisconnectDialogCaptionTxt, MessageBoxButtons.YesNo);

                if (result == DialogResult.Yes)
                {
                    this.dataGridView1.CancelEdit();
                    OnDisconnect();
                }
            }
            else
            {
                OnDisconnect();
            }
        }

        private void OnDisconnect()
        {
            //clear the TreeView
            treeView.Nodes.Clear();

            this.lblLogin.Text = MainResources.LableLoginText;

            //hide controls
            this.TeamProjectsPanel.Visible = false;
            toolStripBtnSave.Visible = false;
            toolStripBtnRefresh.Visible = false;
            toolStripBtnUsersGroupsPicker.Visible = false;
            this.dataGridView1.Visible = false;
            this.actionLogDataGridView.Visible = false;

            //show controls                        
            this.LoginPanel.Visible = true;
            lblHelpMessage.Text = MainResources.HelpMessage2;
        }

        protected override void Dispose(bool disposing)
        {
            if (tfsAppServer != null) { tfsAppServer.Dispose(); }
            if (AppController != null) { AppController.Dispose(); }
            if (adduserIcon != null) { adduserIcon.Dispose(); }
            if (erroruserIcon != null) { erroruserIcon.Dispose(); }
            if (modifyuserIcon != null) { modifyuserIcon.Dispose(); }
            if (newuserIcon != null) { newuserIcon.Dispose(); }
            if (removeuserIcon != null) { removeuserIcon.Dispose(); }
            if (userIcon != null) { userIcon.Dispose(); }
            if (defaultFont != null) { defaultFont.Dispose(); }
            if (selectedFont != null) { selectedFont.Dispose(); }
            if (disposing && (components != null))
            {

                components.Dispose();
            }
            base.Dispose(disposing);
        }
       
    }
}
